package fag.core.game;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import fag.core.collision.Hitbox;
import fag.core.geometry.Rectangle2D;
import fag.core.geometry.Vector2D;

/**
 * Classe abstraite des objets de la scène.
 * @author lumz.
 */
public abstract class AbstractDoodad implements Transformable {

	protected Scene scene = null;
	
	protected AffineTransform transformation = new AffineTransform();
	
	/**
	 * Constructeur par défaut.
	 */
	public AbstractDoodad() {
	}
	
	/**
	 * Accesseur de la boîte englobante.
	 * @return La boîte englobante.
	 */
	abstract public Rectangle2D getBounds();
	
	/**
	 * Accesseur de la boîte de collision.
	 * @return La boîte de collision.
	 */
	abstract public Hitbox getHitbox();
	
	@Override
	public double getRotation() {
	
		double[] flatmatrix = new double[6];
		
		synchronized(transformation) {
			transformation.getMatrix(flatmatrix);
		}
			
		double cos = flatmatrix[0];
		double sin = flatmatrix[1];
		double acos = Math.acos(cos);
		
		if(sin > 0)
			return acos % (2 * Math.PI);
		else
			return -acos % (2 * Math.PI);
	}
	
	@Override
	public AffineTransform getTransformation() {
		
		synchronized(transformation) {
			return (AffineTransform) transformation.clone();
		}
	}
	
	@Override
	public double getTranslationX() {
		
		synchronized(transformation) {
			return transformation.getTranslateX();
		}
	}

	@Override
	public double getTranslationY() {
		
		synchronized(transformation) {
			return transformation.getTranslateY();
		}
	}
	
	@Override
	public Vector2D getTranslation() {
		
		synchronized(transformation) {
			return new Vector2D(transformation.getTranslateX(), transformation.getTranslateY());
		}
	}
	
	@Override
	public void rotate(double angle, Referential referential) {
		rotate(angle, 0, 0, referential);
	}
	
	@Override
	public void rotate(double angle, Vector2D anchor, Referential referential) {
		rotate(angle, anchor.x, anchor.y, referential);
	}
	
	@Override
	public void scale(double sx, double sy, Referential referential) {
		scale(sx, sy, 0, 0, referential);
	}

	@Override
	public void scale(double sx, double sy, Vector2D anchor, Referential referential) {
		scale(sx, sy, anchor.x, anchor.y, referential);
	}
	
	@Override
	public void translate(Vector2D translation, Referential referential) {
		translate(translation.x, translation.y, referential);
	}
	
	@Override
	public void setTranslation(Vector2D translation) {
		setTranslation(translation.x, translation.y);
	}
	
	/**
	 * Dessine l'objet à l'instant présent.
	 * @param graphics2d Le contexte de dessin.
	 */
	abstract protected void draw(Graphics2D graphics2d);
	
	/**
	 * Avancer l'animation de l'intervalle dt.
	 * @param dt L'avancement de l'animation.
	 */
	protected abstract void forward(double dt);
	
	/**
	 * Indiquer la scène dans laquelle l'objet doit apparaître.
	 * @param scene La scène dans laquelle le doodad doit apparaître.
	 */
	protected abstract void setScene(Scene scene);
}
